package com.wejoy.video.middle.station.data.util;

import org.apache.commons.lang.time.DateFormatUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 日期工具类, 继承org.apache.commons.lang.time.DateUtils类
 */
public class DateUtils extends org.apache.commons.lang.time.DateUtils {
    /**
     * 中文月份数组
     */
    public static final String[] NUM_ARRAY = {"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"};

    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM",
            "yyyy-MM-dd HH"};

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd）
     */
    public static String getDate() {
        return getDate("yyyy-MM-dd");
    }

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String getDate(String pattern) {
        return DateFormatUtils.format(new Date(), pattern);
    }

    /**
     * 得到日期字符串 默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String formatDate(Date date, Object... pattern) {
        String formatDate = null;
        if (pattern != null && pattern.length > 0) {
            formatDate = DateFormatUtils.format(date, pattern[0].toString());
        } else {
            formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
        }
        return formatDate;
    }

    /**
     * 得到日期时间字符串，转换格式（yyyy-MM-dd HH:mm:ss）
     */
    public static String formatDateTime(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 得到当前时间字符串 格式（HH:mm:ss）
     */
    public static String getTime() {
        return formatDate(new Date(), "HH:mm:ss");
    }

    /**
     * 得到当前日期和时间字符串 格式（yyyy-MM-dd HH:mm:ss）
     */
    public static String getDateTime() {
        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 得到当前年份字符串 格式（yyyy）
     */
    public static String getYear() {
        return formatDate(new Date(), "yyyy");
    }

    /**
     * 得到当前月份字符串 格式（MM）
     */
    public static String getMonth() {
        return formatDate(new Date(), "MM");
    }

    /**
     * 得到当天字符串 格式（dd）
     */
    public static String getDay() {
        return formatDate(new Date(), "dd");
    }

    /**
     * 得到当前星期字符串 格式（E）星期几
     */
    public static String getWeek() {
        return formatDate(new Date(), "E");
    }

    /**
     * 日期型字符串转化为日期 格式
     * { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
     * "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm",
     * "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm" }
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取过去的天数
     *
     * @param date
     * @return
     */
    public static long pastDays(Date date) {
        long t = new Date().getTime() - date.getTime();
        return t / (24 * 60 * 60 * 1000);
    }

    /**
     * 获取过去的小时
     *
     * @param date
     * @return
     */
    public static long pastHour(Date date) {
        long t = new Date().getTime() - date.getTime();
        return t / (60 * 60 * 1000);
    }

    /**
     * 获取过去的分钟
     *
     * @param date
     * @return
     */
    public static long pastMinutes(Date date) {
        long t = new Date().getTime() - date.getTime();
        return t / (60 * 1000);
    }

    /**
     * 转换为时间（天,时:分:秒.毫秒）
     *
     * @param timeMillis
     * @return
     */
    public static String formatDateTime(long timeMillis) {
        long day = timeMillis / (24 * 60 * 60 * 1000);
        long hour = (timeMillis / (60 * 60 * 1000) - day * 24);
        long min = ((timeMillis / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (timeMillis / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        long sss = (timeMillis - day * 24 * 60 * 60 * 1000 - hour * 60 * 60 * 1000 - min * 60 * 1000 - s * 1000);
        return (day > 0 ? day + "," : "") + hour + ":" + min + ":" + s + "." + sss;
    }

    /**
     * 获取两个日期之间的天数
     *
     * @param before
     * @param after
     * @return
     */
    public static double getDistanceOfTwoDate(Date before, Date after) {
        long beforeTime = before.getTime();
        long afterTime = after.getTime();
        return (afterTime - beforeTime) / (1000 * 60 * 60 * 24);
    }

    /**
     * 获取在当前时间往后增加指定天数的Date
     *
     * @param appendDay
     * @return
     */
    public static Date addAppendDay(int appendDay) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date dt = new Date();
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(dt);
        rightNow.add(Calendar.DAY_OF_YEAR, appendDay);
        return rightNow.getTime();
    }

    /**
     * 获取指定时间前N分钟的Date对象
     * @param date 指定的时间
     * @param minutes 要减去的分钟数
     * @return 指定时间前N分钟的Date对象
     */
    public static Date getDateBeforeMinutes(Date date, int minutes) {
        Calendar calendar = Calendar.getInstance(); // 获取当前时间的日历实例
        calendar.setTime(date); // 设置日历的时间为传入的时间
        calendar.add(Calendar.MINUTE, -minutes); // 减去指定的分钟数
        return calendar.getTime(); // 返回修改后的时间
    }

    /**
     * 获取日期的零点时间
     *
     * @param date
     * @return
     */
    public static Date getStartTimeOfDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取日期的23:59:59:999
     *
     * @param date
     * @return
     */
    public static Date getEndTimeOfDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        return cal.getTime();
    }

    /**
     * 获取昨天日期时间
     *
     * @return
     */
    public static Date getYesterdayDateTime() {
        Calendar cal = Calendar.getInstance();
        cal.add(5, -1);
        return cal.getTime();
    }

    /**
     * 根据开始时间和结束时间返回时间段内的时间集合
     *
     * @param beginDate
     * @param endDate
     * @return List
     */
    public static List<Date> getDatesBetweenTwoDate(Date beginDate, Date endDate) {
        if (beginDate.getTime() >= endDate.getTime()) {
            throw new RuntimeException("endDate must after beginDate ...");
        }
        List<Date> lDate = new ArrayList<Date>();
        lDate.add(beginDate);// 把开始时间加入集合
        Calendar cal = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        cal.setTime(beginDate);
        boolean bContinue = true;
        while (bContinue) {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            cal.add(Calendar.DAY_OF_MONTH, 1);
            // 测试此日期是否在指定日期之后
            if (endDate.after(cal.getTime())) {
                lDate.add(cal.getTime());
            } else {
                break;
            }
        }
        lDate.add(endDate);// 把结束时间加入集合
        return lDate;
    }

    /**
     * 取得昨天0点整时间
     *
     * @return
     */
    public static Date getYesterDayZEROTIME() {
        return getSpecifiedDay(-1, 0, 0, 0);
    }


    /**
     * 获得指定
     *
     * @param day    整数，指定一月中的某天，正数为未来某天时间，负数为过去某天时间
     * @param hour   正整数，一天当中的指定小时数
     * @param minute 正整数，指定分钟数
     * @param second 正整数，指定秒数
     * @return
     */
    public static Date getSpecifiedDay(int day, int hour, int minute, int second) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + day);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 取得今天0点整时间
     *
     * @return
     */
    public static Date getZEROTIME() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * /**
     * 获取当前时间前n个小时德开始与结束后时间
     *
     * @param type 0 开始  1结束
     * @param n    n个小时
     * @return
     */
    public static Date getDateBeforeOneHour(Date date, int type, int n) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - n);
        String dateStr = formatDate(calendar.getTime(), "yyyy-MM-dd HH");
        if (type == 1) {
            return parseDate(dateStr + ":59:59");
        }
        return parseDate(dateStr + ":00:00");
    }

    /**
     * 求两个时间相差的时间单位
     * @param smallDate 小时间
     * @param bigDate  大时间
     * @param type 分别为  Calendar.DATE,Calendar.HOUR,Calendar.MINUTE
     * @return 相差数量
     */
    public static long minusTime(Date smallDate,Date bigDate,int type){
        if(smallDate==null||bigDate==null){
            return Integer.MAX_VALUE;
        }
        long diffMillis = Math.abs(bigDate.getTime() - smallDate.getTime());
        switch (type){
            case Calendar.DATE: return TimeUnit.DAYS.convert(diffMillis, TimeUnit.MILLISECONDS);
            case Calendar.HOUR:return TimeUnit.HOURS.convert(diffMillis, TimeUnit.MILLISECONDS);
            case Calendar.MINUTE:return TimeUnit.MINUTES.convert(diffMillis, TimeUnit.MILLISECONDS);
            default:return Integer.MAX_VALUE;
        }
    }
    /**
     * 获取指定时间的当前小时
     *
     * @param date
     * @return
     */
    public static int getHourByDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    public static long getTimeDifference(String targetTimeStr) {
        // 获取当前时间
        LocalTime now = LocalTime.now();
        // 解析目标时间
        LocalTime targetTime = LocalTime.parse(targetTimeStr);

        // 计算时间差，如果目标时间在过去，则返回负值
        long difference = ChronoUnit.MINUTES.between(now, targetTime);
        return difference;
    }

    /**
     * 判断是否是夏季
     * @return
     */
    public static boolean isSummer() {
        LocalDate currentDate = LocalDate.now();
        int month = currentDate.getMonthValue();
        return month >= 5 && month <= 9;
    }

    public static int getDayOfWeekNumber() {
        // 获取今天的日期
        LocalDate today = LocalDate.now();
        // 获取今天是周几（枚举）
        DayOfWeek dayOfWeek = today.getDayOfWeek();
        // 将DayOfWeek枚举转换为数字1-7
        return dayOfWeek.getValue();
    }

}
